﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Runtime.InteropServices;
using SocketControl.EventArgs;
using SocketControl.Log;
namespace SocketControl.Sync
{
    public class SocketHandle : BaseSocketControl
    {
        #region 事件定义

        /// <summary>
        /// 收到一个请求事件
        /// </summary>
        public override event OnAcceptEvent OnAccept;

        /// <summary>
        /// 接受数据完成事件
        /// </summary>
        public override event OnRecvCompletedEvent OnRecvCompleted;

        /// <summary>
        /// 发送数据完成事件
        /// </summary>
        public override event OnSendCompletedEvent OnSendCompleted;

        /// <summary>
        /// 错误事件
        /// </summary>
        public override event OnErrorEvent OnError;

        #endregion


        /// <summary>
        /// 初始化对像
        /// </summary>
        public SocketHandle()
            : base()
        {
            try
            {
                localsocket = new Socket(this.addressfamily, this.sockettype, this.protocoltype);
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    OnError(e);
                }
                LogHelper.WriteError(this.GetType(), e);
            }
        }

        public SocketHandle(Socket s)
        {
            localsocket = s;
        }

        /// <summary>
        /// 连接
        /// </summary>
        public override void connect(string ip, int port)
        {
            try
            {
                this.exit = true;
                if (localsocket == null)
                {
                    localsocket = new Socket(this.addressfamily, this.sockettype, this.protocoltype);
                }
                ipendpoint = new IPEndPoint(IPAddress.Parse(ip), port);
                localsocket.Connect(ipendpoint);
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    OnError(e);
                }
                LogHelper.WriteError(this.GetType(), e);
            }
        }

        /// <summary>
        /// 绑定
        /// </summary>
        public override void bind(string ip, int port)
        {
            try
            {
                if (localsocket == null)
                {
                    localsocket = new Socket(this.addressfamily, this.sockettype, this.protocoltype);
                }
                ipendpoint = new IPEndPoint(IPAddress.Parse(ip), port);
                localsocket.Bind(ipendpoint);
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    OnError(e);
                }
                LogHelper.WriteError(this.GetType(), e);
            }
        }

        /// <summary>
        /// 监听
        /// </summary>
        public override void listen(int backlog = 100)
        {
            try
            {
                this.localsocket.Listen(backlog);
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    OnError(e);
                }
                LogHelper.WriteError(this.GetType(), e);
            }
        }

        /// <summary>
        /// 接收连接
        /// </summary>
        public override void accept()
        {
            try
            {
                while (exit & this.localsocket.Connected)
                {
                    if (this.localsocket != null)
                    {
                        ///退出有问题，此处处于阻塞状态标志位状态改变不能退出线程；
                        remotesocket = new SocketHandle(this.localsocket.Accept());
                        remotesocket.keepconnect = this.keepconnect;
                        remotesocket.exit = this.exit;
                        if (remotesocket != null)
                        {
                            //收到一个请求
                            if (this.OnAccept != null)
                            {
                                EventCompletedArgs e = new EventCompletedArgs();
                                e.workhandle = this.remotesocket;
                                this.OnAccept(e);
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                if (this.OnError != null)
                {
                    this.OnError(e);
                }
                LogHelper.WriteError(this.GetType(), e);
            }
        }

        /// <summary>
        /// 发送包
        /// </summary>
        public override void send(byte[] buffer, bool depacket = true)
        {
            if (this.localsocket.Connected & exit)
            {
                try
                {
                    if (depacket)
                    {
                        if (buffer != null & buffer.Length > 0)
                        {
                            if (this.localsocket.Connected)
                            {
                                int result = 0;
                                IList<ProtocolParket> sendResult = ProtocolParket.getPacket(buffer);
                                foreach (ProtocolParket sendPacket in sendResult)
                                {
                                    if (this.localsocket.Connected & exit)
                                    {
                                        byte[] tmp = ProtocolParket.Serializable(sendPacket);
                                        LogHelper.WriteInfo(this.GetType(), "\r\n" + Encoding.UTF8.GetString(tmp));
                                        result += this.localsocket.Send(tmp, tmp.Length, SocketFlags.None);
                                    }
                                }
                                //发送数据包完成事件触发
                                if (this.OnSendCompleted != null)
                                {
                                    EventCompletedArgs handle = new EventCompletedArgs();
                                    handle.buffer = buffer;
                                    handle.workhandle = this;
                                    this.OnSendCompleted(handle);
                                }
                            }
                        }
                    }
                    else
                    {
                        LogHelper.WriteInfo(this.GetType(), "\r\n" + Encoding.UTF8.GetString(buffer));
                        int result = this.localsocket.Send(buffer, buffer.Length, SocketFlags.None);
                        //发送数据包完成事件触发
                        if (this.OnSendCompleted != null)
                        {
                            EventCompletedArgs handle = new EventCompletedArgs();
                            handle.buffer = buffer;
                            handle.workhandle = this;
                            this.OnSendCompleted(handle);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (this.OnError != null)
                    {
                        OnError(e);
                    }
                    LogHelper.WriteError(this.GetType(), e);
                }
            }
        }

        /// <summary>
        /// 接收包
        /// </summary>
        public override void recv()
        {
            if (this.localsocket.Connected & exit)
            {
                try
                {
                    SocketError sg = new SocketError();
                    tmp = new byte[0];
                    do
                    {
                        _recvPacket = new byte[recvcache];
                        int result = this.localsocket.Receive(_recvPacket, 0, _recvPacket.Length, SocketFlags.None, out sg);
                        if (result > 0)
                        {
                            
                            byte[] _buff = new byte[result];
                            Array.Copy(_recvPacket, 0, _buff, 0, result);
                            tmp = tmp.Concat(_buff).ToArray();
                            if (result != recvcache)
                            {
                                EventCompletedArgs e = new EventCompletedArgs();
                                e.buffer = tmp;
                                e.workhandle = this;
                                if (this.OnRecvCompleted != null)
                                {
                                    this.OnRecvCompleted(e);
                                }
                            }
                        }
                        else
                        {
                            EventCompletedArgs e = new EventCompletedArgs();
                            e.buffer = tmp;
                            e.workhandle = this;
                            if (this.OnRecvCompleted != null)
                            {
                                this.OnRecvCompleted(e);
                            }
                        }
                    } while (keepconnect & exit & this.localsocket.Connected);
                }
                catch (Exception e)
                {
                    if (this.OnError != null)
                    {
                        this.OnError(e);
                    }
                    LogHelper.WriteError(this.GetType(), e);
                }
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public override void close()
        {
            base.close();
        }
    }
}
